#!/usr/bin/python
# coding=utf8
import codecs
# simply vCard parser, 
# currently only handle, names, mails and phones

# license: GPL
# author: Pavel Nemec <pnemec@suse.cz>
# 2007-06-29 HACK WEEK

class ReadVcard:

	list # list of filled contacts  
	file="" #name of file
	def __init__(self):
		self.files=[]
		self.newFiles=[]
		self.list=[]
		self.parsed="false"
	def addFile(self, file):
		print "RVC. addingFile: ",file
		self.newFiles.append(file)
		self.parsed="false"
	def parseAllFiles(self):
		self.list=[]
		self.newFiles+=self.files
		self.files=[]
		self.pardsed="false"
		self.parseNewFiles()
		
	def parseNewFiles(self):
		
		for file in self.newFiles:
			try:
					fr = codecs.open(file,'r', encoding='utf-8')
					#fr = open(file, 'r')
			except IOError:
				print 'Error:  Couldn\'t parse file: .', file
				continue;
			print "going parse: ", file
			line=fr.readline()
			while line!="":
				if line.startswith("BEGIN:VCARD"):
					#PARSING NEW VCARD
					#print "new vcard"
					line = fr.readline()
					c = Contact()
					while line!="":
						#print "\t",line
						if line.startswith("END:VCARD"): break
						if line.startswith("FN:"): 
							line = line.replace("FN:","")
							line = line.replace("\n","")
							c.storeName(line)
							#print "storing name: ",line
						
						if line.startswith("N:"):  #another format for maili
							line = line.replace("N:","")
							#print "have an N name ", line
							parts = line.split(";")
							if (len(parts)>1): c.storeName(parts[1]+ " "+ parts[0])
							else: c.storeName(parts[0])
							#print "storing name: ",parts[1]+ " "+ parts[0]
						if line.startswith("EMAIL"):	 
						   # print "have an email", line
							type="Home"
							mail= line.rpartition(':')[2] #parts[2] is mail
							
							if line.find("type")!=-1:
								parts = line.partition("type=")
								if parts[2].find(";")!=-1:
									type = parts[2].split(';')[0]
								else:
									type = parts[2].split(':')[0]
							if line.find("TYPE")!=-1:
#								print "have an type"
								parts = line.split("TYPE=")
								if parts[1].find(";")!=-1:
									type = parts[1].split(';')[0]
								else:
									type = parts[1].split(':')[0]
							type = type.replace('\n',"")
							mail = mail.replace('\n',"")
							c.storeEmail(type,mail)
						if line.startswith("TEL"):
							type="Home"
							tel= line.rpartition(':')[2] #parts[2] is tel
							
							#we have somethink like
								#TEL;type=blablab;type=pref:email@email
								#or
								#TEL;type=blablab:email@email
							if line.find("type")!=-1:
								parts = line.partition("type=")
								if parts[2].find(";")!=-1:
									type = parts[2].split(';')[0]
								else:
									type = parts[2].split(':')[0]
							if line.find("TYPE")!=-1:
#								print "have an type"
								parts = line.split("TYPE=")
								if parts[1].find(";")!=-1:
									type = parts[1].split(';')[0]
								else:
									type = parts[1].split(':')[0]
  #						  print "using type: ",type
							type = type.replace('\n',"")
							tel = tel.replace('\n',"")
							c.storePhone(type,tel)
		
						if line.startswith("PHOTO"):
							pass
#							print "have an photo: ",line, " skipping"
						if line.startswith("X-AIM"):
							parts=line.split(":")
							c.storeIM("AIM",parts[len(parts)-1])
						if line.startswith("X-ICQ"):
							parts=line.split(":")
							c.storeIM("ICQ",parts[len(parts)-1])
						if line.startswith("X-messaging"):
							#some crap like X-messaging/groupwise-All:account
							type=line[line.find("/")+1:line.find("-All")]
							im=line[line.rfind(":")+1:len(line)]
							c.storeIM(type,im)
						line=fr.readline()
					self.list.append(c)
				   # print "end of vcard ",line
				   
				line=fr.readline()
			self.parsed="true"
			self.files+=self.newFiles;
			self.newFiles=[]
			print "parse finished, having ",len(self.list), " items"
	def search(self, chars):
		
		if self.parsed=="false":
			self.parseNewFiles()
		reti=[]
		for i in range(len(self.list)):
			contact=self.list[i];
			if contact.find(chars):
				#print " contact with name: ",contact.jmeno, " is ok"
				item=[i,contact.getId()]
				reti.append(item)
		return reti
	def getItemCount(self):
		return len(self.list)
	def getContact(self, id):
		if id> len(self.list) or id<0: 
			print "rvc error, wrong id: ",id
			return
		else: return self.list[id]
	def clear(self):
		self.files=[]
		self.newFiles=[]
		self.list=[]
			
class Contact:
	def __init__(self):
		self.jmeno=""
		self.phoneList=[]
		self.mailList=[]
		self.imList=[]
	def storeName(self, name):
		self.jmeno=name
		#print "Jmeno: ",name , "stored"
	def storeEmail(self,type, email):
		mail =[type,email]
		self.mailList.append(mail)
	   # print "adding mail ",mail
	def storePhone(self,type, tel):
		phone =[type,tel]
		self.phoneList.append(phone)
		#print "adding phone ",phone
	def storeIM(self,type,im):

		imtype=[type,im]
		self.imList.append(imtype)
	def find(self,chars):
		# here is little big slow down, lovering and replacing can be done one for all
		# contact, @todo
		chars=chars.lower() # search for all posibility lower all
		chars=chars.replace(" ","") # do not let space prevent as finding what we want
		chars = self.removeUmlauf(chars) #doesnt work yet :(
		found =False
		#print "seraching for: ",chars
		#print "name: ",self.jmeno, " searching for: ", chars
		tmp=self.jmeno.lower()
		tmp=tmp.replace(" ","") #rid of white space
		tmp=self.removeUmlauf(tmp) #doesnt work yet :(
		if tmp.find(chars)!=-1 :
		  #  print self.jmeno, " found "
			found=True
			return found
		for phone in self.phoneList[:]:
			tmp=phone[0].replace(" ","")
			if tmp.find(chars)!=-1:
				found=True
				return found
			tmp=phone[1].replace(" ","")
			if tmp.find(chars)!=-1:
				found=True
				return found
		for mail in self.mailList[:]:
			tmp=mail[0].lower() #ther should be no white space in mail, we do not need to call .replace(" ","")
			if tmp.find(chars)!=-1:
				found=True
				return found
			tmp=mail[1].lower()
			if tmp.find(chars)!=-1:
				found=True
				return found
		for im in self.imList[:]:
			tmp=im[1].lower()
			if tmp.find(chars)!=-1:
				found=True
				return found
		return found
	def getId(self):
		return self.jmeno
	def toString(self):
		reti=self.jmeno+"\n"
		for phone in self.phoneList:
			reti+= "phone: ("+phone[0]+ "): "+ phone[1] +"\n"
		for mail in self.mailList:
			reti+= "mail: ("+mail[0]+ "): "+mail[1]+"\n"
		for im in self.imList:
			reti+= "im: ("+im[0]+ "): "+im[1]+"\n"
		return reti
	
	def removeUmlauf(self,chars):
		return chars
		''' ok not umlauf, but interpunction for now, expecting .lover() is allready called'''
		charsToRemove=['ž','š','č','ř','č','ď','ť','ň']
		reti=chars
		for i in charsToRemove:
			reti=reti.replace(i,"")
		return reti
def test():
	'''Test method to test Contact class'''
	rvc  =   ReadVcard ()
	rvc.addFile("/home/thidney/Desktop/vcards4.vcf")
	rvc.addFile("/home/thidney/Desktop/addressbook.vcf")
	rvc.addFile("/home_local/pnemec_local/Desktop/addressbook.vcf")
	
	#rvc.parseAllFiles()
	search="pavel"
	list = rvc.search(search)
	print "search for: ", search, " ", len(list), " items"
	for i in list[:]:
		c = rvc.getContact(i[0])
		print c.toString()

def main():
	test()

if __name__=="__main__":
	main()
